using System;
using System.Collections;
using System.Data;
using System.Data.SqlClient;

using NHibernate;
using NHibernate.Engine;

namespace BEGDC.Utility.NHibernate
{
	/// <summary>
	/// Summary description for NHibernateUtil.
	/// </summary>
	public class NHibernateUtil
	{
		public static DataTable Execute(ISession dbSession, string queryString)
		{
			DataTable table = null;
			IDbCommand cmd = dbSession.SessionFactory.ConnectionProvider.Driver.CreateCommand();
			cmd.CommandText = queryString;
			IDbConnection conn = dbSession.Connection;

			cmd.Connection = conn;
			if (dbSession.Transaction != null)
				dbSession.Transaction.Enlist(cmd);

			if(cmd.GetType() == typeof(SqlCommand))
			{
				SqlDataAdapter da = new SqlDataAdapter((SqlCommand)cmd);
				DataSet ds = new DataSet();
				da.Fill(ds);
				if(ds.Tables[0] != null)
					//table = ds.Tables[0].Copy();
					table = ds.Tables[0];
			}
			return table;
		}

		public static IList ExecuteQuery(ISession dbSession, string queryString)
		{
			IList result = new ArrayList();
			IDbCommand cmd = dbSession.SessionFactory.ConnectionProvider.Driver.CreateCommand();
			cmd.CommandText = queryString;
			IDbConnection conn = dbSession.Connection;
			cmd.Connection = conn;
			if (dbSession.Transaction != null)
				dbSession.Transaction.Enlist(cmd);

			IDataReader rs = cmd.ExecuteReader();
			while ( rs.Read() )
			{
				int fieldCount = rs.FieldCount;
				object[] values = new Object[ fieldCount ];
				for ( int i = 0; i < fieldCount; i ++ )
					values[i] = rs.GetValue(i);
				result.Add( values );
			}
			return result;
		}

		public static int ExecuteNonQuery(ISession dbSession, string sqltring)
		{
			IDbCommand cmd = dbSession.SessionFactory.ConnectionProvider.Driver.CreateCommand();
			cmd.CommandText = sqltring;
			IDbConnection conn = dbSession.Connection;
			cmd.Connection = conn;
			if (dbSession.Transaction != null)
				dbSession.Transaction.Enlist(cmd);
			return cmd.ExecuteNonQuery();
		}

        public static T ExecuteScalar<T>(ISession dbSession, string sqltring) where T : class
        {
            if (dbSession == null)
            {
                throw new ArgumentNullException("dbSession");
            }

            if (string.IsNullOrEmpty(sqltring))
            {
                throw new ArgumentException("SQL string cannot be empty.");
            }

            using (IDbCommand cmd = dbSession.SessionFactory.ConnectionProvider.Driver.CreateCommand())
            {
                cmd.CommandText = sqltring;

                cmd.Connection = dbSession.Connection;

                if (dbSession.Transaction != null)
                {
                    dbSession.Transaction.Enlist(cmd);
                }
                return cmd.ExecuteScalar() as T;
            }
        }

		public static void FillDataSet(ISession dbSession, string queryString, DataSet dataSet)
		{
			IDbCommand cmd = dbSession.SessionFactory.ConnectionProvider.Driver.CreateCommand();
			cmd.CommandText = queryString;
			IDbConnection conn = dbSession.Connection;

			cmd.Connection = conn;
			if (dbSession.Transaction != null)
				dbSession.Transaction.Enlist(cmd);

			if(cmd.GetType() == typeof(SqlCommand))
			{
				SqlDataAdapter da = new SqlDataAdapter((SqlCommand)cmd);
				da.Fill(dataSet);
			}
		}
	}
}